About the Programs Listings 1 and 2 enable you to experiment with the relaxation method if you have a computer that runs Microsoft BASIC. These listings, as is, run on an Apple II computer in 40-column mode, but only the subroutines at lines 10000 and 14000 in listing 1 and lines 10000 and 23000 in listing 2 (which implement file input from and output to disk) must be changed to get this program to work on machines like the Radio Shack Model IV, the IBM Personal Computer, the Commodore 64 and VIC, and other computers. You may want to change the print-array routines at line 20000 in each program to display data in the best way for your com puter; these routines were written to display data neatly on an 80-column printout. All REM statements can be removed, and all variables can be shortened to their first two characters. Variable names are sometimes spelled oddly; this is to ensure that they don't conflict with BASIC reserved words and other variables. (In Applesoft and some other Microsoft BASICs, only the first two characters of a variable name are remembered.) In addition, try larger array sizes for the DIM (dimension) statements of both programs. Your computer may have more space available than mine does. Listing 1 is the program I call EDITOR. With this program, you can create a new data file or modify a data file; modifications include changing elements, changing the size of the array, or expanding the array to twice its size. Listing 2, the program called RELAXN, reads this data file, does the relaxation in a semiautomated fashion, prints intermediate and final results, and enables you to save the final result onto disk for later manipulation. The data file used by both programs has the following contents: first, the number of rows in the input array; second, the number of columns; third, a numeric value that represents an inactive node (called the "inactive number"); and, finally, the elements of the input array listed by rows. The input array needs some explanation because it is used to represent several different kinds of data. I created the inactive number so these programs could work with rounded cross sections. The inactive number can be any value not otherwise found in the input array. You should use it only in the corners of the array to make a rounded shape fit into a rectangular array. The second kind of data is the boundary elements. The RELAXN program looks at the input array and flags the outermost layer of numbers (ignoringinactive nodes, if any) as boundary elements. The third kind of data is any elements left; these represent the initial values of the interior nodes in the cross section. The RELAXN program reads the input array into the NODE array and, before manipulating it, creates a same-sized MASK array that stores the type of each element. Inactive elements have a MASK value of -1, boundary elements have a value of 0, and interior elements have a MASK of 1. The program checks this array often to prevent doing inappropriate operations on any given element. The notes for listing 1 provide a commentary on the EDITOR pro- gram, which is pretty straightforward. You can start a data file from scratch or read in a previously existing one. You can change the array by row, column, or individual element. You can change the size of an array loaded in from disk and also expand an array to twice its size (actually, from m-by-n to (2m-1)-by-(2n-1)). This option, discussed in the main text, is used to get more accurate results. When you choose to expand the input array, the computer tries to interpolate the values of added elements in a context-sensitive way. It usually does a good job, but you should inspect the resulting array and patch up any flaws. The notes for listing 2 provide a commentary on the RELAXN program. The program reads in the input array, creates the MASK and RESID arrays, lets you do block relaxations (if desired), repeats the main loop of the iteration algorithm until the RESID array is within the specified range of accuracy, prints out the result, and allows you to save the solved NODE array for later use. The program also lets you set the number of iterations to be performed before the NODE and RESID arrays are to be printed, gives you a warning message if the relaxation "hangs" on a single node (which sometimes denotes the end of the algorithm at that level of accuracy before the official criteria for ending are fulfilled), and lets you abort the algorithm and save your results. I wrote this program to be as simple and clear as possible; there are numerous optimizations I did not perform, leaving that to the enterprising programmer. These two programs were designed us ing a structured flowchart format I described three years ago (see "Structured Programming and Structured Flowcharts,' March 1981 , page 20). The structured flowcharts were then translated into BASIC code, whcih accounts for the occasionally unconventional use of GOTOs in the programs. I reluctantly chose BASIC over Pascal because BASIC is still the lingua franca of BYTE readers--a recent study we did showed that 77% of our readers use BASIC most often, while 21% use some kind of assembly language, and only 15% use Pascal. One final note: I must confess to the use of a quick-and-dirty shortcut concerning the block relaxation subroutine in RELAXN. Instead of actually implementing the block relaxation algorithm (which decreases the number of computations to relax a block of elements by the same amount), I had the computer execute a double- nested do-loop that relaxed each element individually. You should implement the true block relaxation algorithm if you are going to be doing many large block relaxations. Mea culpa, mea maxima culpa. Program Notes for Listing 1 Line Group Function 181-195 Loads in an array from disk; you have the otions of expanding the array (line 184) or arbitrarily changing its size (line 188). 200-210 Gets the size of the array (MROWS, MCOLS) and the value of the "inactive' element (INACTIVE) the array is being built from scratch. 410-465 Gets a row of values; this section repeats until you give it -1 for a row number 472-486 Gets a column of values; this section repeats until you give it -1 for a column number 505-550 Gets an individual element to change; this section repeats until you give it a -1,0,0 to end it 600-630 Saves the file to disk. Subroutines 10000-10060 Reads data file from disk. 11000-11500 Expands array A to a twice-sized array B. Does interpolation to fill in missing values. If one of the two values used for interpolation is the inactive element, the value being interpolated is set equal to the active element. 14000-14060 Writes data file to disk. 20000-20420 Displays the array being worked on (array B). Because the array may have more columns than can be printed on an 80-column printer, I wrote this routine to display C10LPERPAGE columns at a time; I can then paste these strips together to get the entire array. You may want to change the value of C10LPERPAGE or write a more efficient, implementation-specific subroutine. Program Notes for Listing 2 210-220 Reads input file. 300 Creates MASK array from input array. 380 Sets flag MANUAL$, which determines whether you can do point relaxations from the keyboard after every printout of the NODE and RESID arrays. 400-410 Gets the desired number of decimal places of accuracy and computes the values of two error- limit values, ERR (maximum error for any one element) and ESUM (maximum error for sum of all error values). 500 Calculates the value of the RESID array. 600-660 Enables you to do block relaxation; this section of code repeats until you answer N to the question in line 605. 800 Checks to see if relaxation algorithm is finished. If it is (very unlikely), QUIT$ is set to Y. 900 Gets the number of iterations to be performed, ITERLEFT, before the NODE and RESID arrays are printed. 1000-1300 Main loop of program, repeated until QUIT$ becomes Y. Its main events are doing a point relaxation on the element that needs it most (line 1103), and evaluating RESID for end-of-algorithm (setting QUITE$ to Y if the conditions are met-- line 1200). Each time through this loop, ITERLEFT is decremented by 1; if it goes to 0, the NODE and RESID arrays are printed (line 1160), you get a chance to quit the program prematurely (if it "hangs" on certain values--line 1240), and the program gets a new value for ITERLEFT (line 1242). In certain circumstances, the variation this algorithm gives is too "coarse" to adjust the RESID array below the given error threshold. This usually results in the program relaxing the same node endlessly. The program gives you a warning if it detects that the same node has been relaxed twice in a row. 1400-1420 Gives you a chance to do manual relaxation to fine-tune the NODE array before saving it to disk. 1500-1530 Recalculates the RESID array from the NODE array and rechecks to ensure that the NODE array actually meets the terminating conditions. The program does this because each relaxation adjusts the NODE and RESID arrays, and roundoff errors may have accumulated. 2000-2110 Gives you the option to save the NODE data to a disk data file. RESID is not saved because it can be directly calculated from NODE. Subroutines 15000-15620 Creates MASK array from input array (which is contained in the NODE array variable). All non- INACTIVE values on the first and last rows are considered to be border elements. On all other rows, the rows are inspected from the ends inward; the first non-INACTIVE value on each end is taken to be a border element. All the elements framed by the two border elements are taken to be active (interior) elements. Inactive elements are marked by 1, border elements by 0, active elements by 1 in MASK. 17000-1720 Relaxes node (I,J) by the amount N. The RESID values are changed according to the relaxation template only if the node is an active, interior one; border and inactive elements are not changed. 19000-19210 Does a block relaxation given the upper-left corner element (RLO, CLO) and lower-right corner element (RHI, CHI). This routine automatically calculates the number of units for the block to be relaxed in line 19080. 20000-20420 Prints the NODE and RESID arrays. See the reference to line 20000 in the program notes for listing 1. 21000-21200 Evaluates the RESID array to determine if the program is finished (see line 21120). If so, QUIT$ is set to Y. 22000-22200 Finds the element with the largest RESID value and relaxes it to 0. 23000-23060 Saves the NODE array and related information to disk. This data file can be read again by either the EDITOR or RELAXN programs. 24000-24080 Enables you to do point relaxations from the keyboard. ain by either the EDITOR or RELAXN programs. 24000-24080 Enables you to do point relaxations from